{-# LANGUAGE DeriveDataTypeable, TypeOperators, ExistentialQuantification #-}

module Sim.Types
  ( Context(..)
  , Env(..)
  , Device(..)
  , CCD(..)
  , Objects(..)
  , Integrator(..)
 
  , OperationMode(..)
  , DisperserType(..)
  , PSFType(..)
  , FieldType(..)

  , module Sim.PhysTypes
  ) where

import Data.Typeable ( Typeable )
import Sim.PhysTypes
import Sim.PSF       ( PSF )
import Sim.ObsObject ( ObsObject )

data OperationMode = Imaging | SlitlessSpectroscopy             deriving (Read, Show, Typeable)
data DisperserType = TypeGrism | TypePrism | TypeNone           deriving (Read, Show, Typeable)
data PSFType       = Gauss (Double,Double) | CustomPSF FilePath deriving (Read, Show, Typeable)
data FieldType     = RandomStars Int | CustomField FilePath     deriving (Read, Show, Typeable)

data Integrator = Integrator { limits :: (Double, Double)
                             , step   :: Double
                             , quad   :: (Double -> Double) -> Double
                             }

data    Context =    Context { env   :: Env
                             , dev   :: Device
                             , ccd   :: CCD
                             , obj   :: Objects
                             , int   :: Integrator
                             }

data    Device =      Device { title              :: String
                             , fieldView          :: FiledView
                             , ccdArray           :: [CCD]
                             , disperser          :: ADF
                             , sensitivity        :: Sensitivity
                             }

data       CCD =         CCD { fpposition         :: !(Double,Double)
                             , ffposition         :: !(Int,Int)
                             , position           :: !(Int,Int)
                             , width              :: !Int
                             , height             :: !Int
                             , thickness          :: !Double
                             , area               :: !Double
                             , bias               :: !Double
                             , darkNoise          :: !Double
                             , readNoise          :: !Double
                             , maxLevel           :: !Double
                             , quantumEfficiency  :: !Sensitivity
                             , psf                :: !PSF
                             }

data   Objects =     Objects { objs               :: ![ObsObject]
                             , magFilter          :: !Filter
                             , atlasSpectralTypes :: !( EnergyDist, [(SpType, EnergyDist)] )
                             }

data       Env =         Env { expTime            :: !Double
                             , crFlux             :: !Double
                             , psfType            :: !PSFType
                             , opMode             :: !OperationMode
                             , fldType            :: !FieldType
                             , output             :: !FilePath
                             }